﻿using SuperX.Common.BasicService;
using SuperX.Common.Helper;
using SuperX.SuperSocket;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace SuperX.DataCenterService.WebAPI
{
    public class WebApiController : ControllerBase
    {
        [HttpPost("/api/{service}/{moduleAction}")]
        public object Invoke(string service, string moduleAction, [FromBody] object[] Request)
        {
            return RpcProcessor.ExecutionAction(service, moduleAction, Request);
        }

        [HttpPost("/Download/{service}/{moduleAction}")]
        public async Task<IActionResult> Download(string service, string moduleAction, [FromBody] object[] Request)
        {
            var FileDownloadName = "*";
            var fileBytes = await Task.Run(() =>
            {
                if (!(RpcProcessor.ExecutionAction(service, moduleAction, Request) is string filepath && System.IO.File.Exists(filepath)))
                    return null;
                FileDownloadName += Path.GetExtension(filepath);
                Response.Headers.Add("Access-Control-Expose-Headers", "FileSHA,Content-Disposition");
                Response.Headers.Add("FileSHA", Helper.NOPI.FileMD5.SHA256File(filepath));
                return System.IO.File.ReadAllBytes(filepath);
            });
            if (fileBytes is null)
                return StatusCode(StatusCodes.Status406NotAcceptable);
            return new FileContentResult(fileBytes, "application/octet-stream")
            {
                FileDownloadName = FileDownloadName
            };
        }

        [HttpPost("/WebApi/UploadFile")]
        public async Task<IActionResult> UploadFile(IFormCollection UpInfo)
        {
            if (UpInfo.Count <= 0) return StatusCode(StatusCodes.Status406NotAcceptable);
            var action = Request.Form["Action"].ToString();
            var controller = Request.Form["Controller"].ToString();
            var filesSHA = Request.Form["FilesSHA"].ToString();
            var shaAll = JsonHelper.JsonDeserialize<string[]>(filesSHA);
            var parameters = Request.Form["Parameters"].ToString() == null ? "[]" : Request.Form["Parameters"].ToString();
            var request = JsonHelper.JsonDeserialize<List<object>>(parameters);
            var upLoadFileInfo = await GetUpLoadFileInfo(UpInfo, shaAll);
            if (upLoadFileInfo is null)
                return StatusCode(StatusCodes.Status406NotAcceptable);
            request.Add(upLoadFileInfo);
            return new JsonResult(RpcProcessor.ExecutionAction(controller, action, request.ToArray()));
        }

        public Task<List<Helper.NOPI.UpLoadFileInfo>> GetUpLoadFileInfo(IFormCollection UpInfo, string[] shaAll)
        {
            string root = Path.Combine(BasicServiceManager.GetProjService().Project.ProjectDir, "Runtime", "UpLoad");
            if (!Directory.Exists(root)) { Directory.CreateDirectory(root); }
            return Task.Run(() =>
            {
                var list = new List<Helper.NOPI.UpLoadFileInfo>();
                for (int i = 0; i < UpInfo.Files.Count; i++)
                {
                    var fileName = Path.Combine(root, "BodyPart_" + Guid.NewGuid());
                    using (var stream = new FileStream(fileName, FileMode.Create)) { UpInfo.Files[i].CopyTo(stream); }
                    var upLoadFileInfo = new Helper.NOPI.UpLoadFileInfo()
                    {
                        UploadName = UpInfo.Files[i].FileName,
                        LocalFileName = fileName
                    };
                    if (upLoadFileInfo.SHA256File != shaAll[i]) return null;
                    list.Add(upLoadFileInfo);
                }
                return list;
            });
        }
    }
}